package com.tyq.client.oauth2;

import com.tyq.client.security.access.MyAccessDecisionManager;
import com.tyq.client.security.handler.MyAccessDeniedHandler;
import com.tyq.client.security.handler.MyAuthenticationEntryPoint;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;

import javax.annotation.Resource;

/**
 * 资源服务器
 *
 * @author 谭永强
 * @date 2024-05-20
 */
@Configuration
@EnableResourceServer
public class Oauth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

    /**
     * 资源ID
     */
    private final static String RESOURCE_ID = "order";
    @Resource
    private MyAccessDeniedHandler myAccessDeniedHandler;
    @Resource
    private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
    @Resource
    private MyAccessDecisionManager myAccessDecisionManager;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                //请求拦截器
                .authorizeRequests()
                //设置不需要认证的请求
                .antMatchers(HttpMethod.OPTIONS).permitAll()
                //所有请求都要认证
                .anyRequest().authenticated()
                //自定义访问决策管理器
                .accessDecisionManager(myAccessDecisionManager)
                .and()
                //关闭cors防护
                .cors().disable()
                //关闭csrf防护
                .csrf().disable()
                //使用JWT，关闭session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources
                //资源ID(可选)，但是推荐设置并在授权服务器中进行验证
                .resourceId(RESOURCE_ID)
                //自定义无权限请求处理器
                .accessDeniedHandler(myAccessDeniedHandler)
                //自定义未认证请求处理器
                .authenticationEntryPoint(myAuthenticationEntryPoint)
                //使用远程认证服务器验证令牌
                .tokenServices(tokenServices());
    }

    /**
     * 资源服务令牌解析
     *
     * @return 远程令牌服务
     */
    private ResourceServerTokenServices tokenServices() {
        RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        remoteTokenServices.setClientId("Browser");
        remoteTokenServices.setClientSecret("BrowserSecret");
        remoteTokenServices.setCheckTokenEndpointUrl("http://127.0.0.1:8080/oauth/check_token");
        return remoteTokenServices;
    }
}
